package cn.swanit.iot.verticles;

import cn.swanit.iot.contant.EventBusAddress;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.net.NetServer;
import io.vertx.core.net.SocketAddress;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * description
 * company 铁人科技
 *
 * @author 陈浩杰
 * @date 2022/11/2 15:20
 */
@Slf4j
@Setter
public class TcpServerVerticle extends AbstractVerticle {

    private NetServer netServer;

    private final String host;

    private final int port;

    public TcpServerVerticle(int port) {
        this.host = "0.0.0.0";
        this.port = port;
    }

    public TcpServerVerticle(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @Override
    public void start(Promise<Void> startPromise) throws Exception {
        EventBus eventBus = vertx.eventBus();
        this.netServer = vertx.createNetServer();

        // 处理连接请求
        netServer.connectHandler(socket -> {
            SocketAddress socketAddress = socket.remoteAddress();
            log.info("客户端连接成功===host==={}===port=={}===", socketAddress.host(), socketAddress.port());
            socket.handler(buffer -> {
                String msg = buffer.toString();
                // 在这里应该解析报文，封装为协议对象，并找到响应的处理类，得到处理结果，并响应
                log.info("接收到的数据为{}", msg);
                System.out.println("接收到的数据为:" + msg);
                // 按照协议响应给客户端
                socket.write(Buffer.buffer("Server Received"));
                eventBus.localConsumer(EventBusAddress.DEMO_ADDRESS, mh -> {
                    Object body = mh.body();
                    socket.write(Buffer.buffer(body.toString()));
                });
            });

            // 监听客户端的退出连接
            socket.closeHandler(close -> {
                log.info("客户端退出连接");
            });
            // 监听客户端的异常退出
            socket.exceptionHandler(e -> {
                log.info("客户端异常退出");
            });
        });

        netServer.exceptionHandler(e -> {
            log.info("服务端异常{}", e.getMessage());
        });

        // 监听端口
        netServer.listen(port, host, res -> {
            if (res.succeeded()) {
                startPromise.complete();
            } else {
                startPromise.fail(res.cause());
            }
        });
    }

    @Override
    public void stop(Promise<Void> stopPromise) {
        netServer.close(event -> {
            if (event.succeeded()) {
                stopPromise.complete();
            } else {
                stopPromise.fail(event.cause());
            }
        });
    }
}
